const cvs = document.querySelector('canvas')
const ctx = cvs.getContext('2d', {
  willReadFrequently: true,
})
const inpColor = document.querySelector('input[type=color]')

function init() {
  const img = new Image()
  img.crossOrigin = ''
  img.onload = () => {
    cvs.width = img.width
    cvs.height = img.height
    ctx.drawImage(img, 0, 0)
  }
  img.src =
    'https://img1.baidu.com/it/u=3518673092,2032183538&fm=253&fmt=auto&app=138&f=JPEG?w=781&h=500'
}

init()

function points2Index(x, y) {
  return (y * cvs.width + x) * 4
}
function hex2RGBA(hex) {
  const r = parseInt(hex.slice(1, 3), 16)
  const g = parseInt(hex.slice(3, 5), 16)
  const b = parseInt(hex.slice(5, 7), 16)
  return [r, g, b, 255]
}

cvs.addEventListener('click', (e) => {
  const clickX = e.offsetX
  const clickY = e.offsetY
  // 获取范文内的像素信息
  const imgData = ctx.getImageData(0, 0, cvs.width, cvs.height)
  const cvsColors = imgData.data
  const hex = inpColor.value
  const targetColor = hex2RGBA(hex)
  const originColor = getColor(clickX, clickY, cvsColors)
  changeColor(clickX, clickY, cvsColors, targetColor, originColor)
  ctx.putImageData(imgData, 0, 0)
})
function getColor(x, y, cvsColor) {
  const index = points2Index(x, y)
  return cvsColor.slice(index, index + 4)
}

function diff(color1, color2) {
  return (
    Math.abs(color1[0] - color2[0]) +
    Math.abs(color1[1] - color2[1]) +
    Math.abs(color1[2] - color2[2]) +
    Math.abs(color1[3] - color2[3])
  )
}

function changeColor(x, y, cvsColor, targetColor, originColor) {
  if (x < 0 || y < 0 || x >= cvs.width || y >= cvs.height) {
    return
  }
  const index = points2Index(x, y)
  const currentColor = getColor(x, y, cvsColor)
  if (diff(currentColor, targetColor) === 0) {
    return // 该像素点更改过了
  }
  if (diff(currentColor, originColor) > 50) {
    return // 该像素点与原点颜色差距过大
  }

  cvsColor.set(targetColor, index)
  changeColor(x - 1, y, cvsColor, targetColor, originColor)
  changeColor(x + 1, y, cvsColor, targetColor, originColor)
  changeColor(x, y - 1, cvsColor, targetColor, originColor)
  changeColor(x, y + 1, cvsColor, targetColor, originColor)
  // cvsColor[index] = targetColor[0]
  // cvsColor[index+1] = targetColor[1]
  // cvsColor[index+2] = targetColor[2]
  // cvsColor[index+3] = targetColor[3]
}
